﻿package code {
	import flash.display.Sprite;
	// class is main gameobject.  Basically what everything in the game is made out of
	public class GameObject extends Sprite {
		public var ax:Number;  // the acceleration in x direction
		public var ay:Number;  // acceleration in the y direction
		public var vx:Number;  // velocity in x direction
		public var vy:Number;  // velocity in y direction
		public var shapeType:String;  // type of shape the object is 
		public var shape:BaseShape;   // the stored shape
		public var isDeformed:Boolean;
		public var scale:Number;
		public var scaleTimer:Number;
		
		//Skew Variables
		public var skewX:Number;		
		public var tempX:int;		
		public var oldX:Number;
		
		public const SCALE_TIME = 200;
		public function GameObject(sType:String, radius:Number, sides:Number, color:uint, thickness:Number, hollow:Boolean, angle:Number = 0, lineHeight:int = 0, thirdVertex:Vertex = null, spinnerLength:Number = 0) {
			ax = 0;
			ay = 0;
			vx = 0;
			vy = 0;
			skewX = .3; //Skew value
			scaleTimer = 0;
			shapeType = sType;
			isDeformed = true;
			init(shapeType, radius, sides, color, thickness, hollow, angle, lineHeight, thirdVertex, spinnerLength);
		}
		
		// initializes the game object based on the shape
		private function init(shapeType:String, radius:Number, sides:Number, color:uint, thickness:Number, hollow:Boolean, angle:Number, lineHeight:int = 0, thirdVertex:Vertex = null, spinnerLength:Number = 0){
			if(shapeType == "Polygon"){  
				shape = new Polygon(radius, sides, color, thickness, hollow, angle);
			}
			else if(shapeType == "Rectangle"){
				shape = new Rect(radius, sides, color, thickness, hollow, angle, lineHeight); // rectangles need a line height
			}
			else if(shapeType == "Triangle"){
				shape = new Triangle(radius, sides, color, thickness, hollow, angle, lineHeight, thirdVertex); // triangle need a third vertex
			}
			else if(shapeType == "SpinGon"){
				shape = new SpinGon(radius, sides, color, thickness, hollow, angle, spinnerLength);
			}
			
			addChild(shape);  // add shapes as a child of gameobject
		}
		
		// method creates array of lines based off of the shape.  Must be created after x and y are assigned
		public function createLinesArray():Array{
			var verticesToPush = new Array();  // array of vertices to check.  Kept seperate from main vertices of shape
			var linesToPush = new Array();	// the lines to push in the main game class. A debugging feature to see how it would work
			
			if(shape.vertices.length > 0){  // to prevent a glitch where the we were getting null vertices
				for each(var v:Vertex in shape.vertices){
					verticesToPush.push(new Vertex(v.x + x, v.y + y)); // pushes all the vertices
				}
				verticesToPush.push(new Vertex(shape.vertices[0].x + x, shape.vertices[0].y + y));  // pushes the first vertex so it will loop back
				for(var i:int = 0; i < verticesToPush.length - 1; i++){	// goes through the vertices and creates line out of them
					var tempLine:Line = new Line(verticesToPush[i], verticesToPush[i + 1], 3, 0x000000);  // creates the temp line to push
					tempLine.go = this;

					shape.linesArray.push(tempLine);  // stores it in shape
					linesToPush.push(tempLine);  // puts them into the output debug array
					
				}
			}
			return linesToPush;
		}
		
		// updaetes the tween of the object position 
		public function updateObject(timeChange:Number){
			if(!isDeformed)
				scaleTimer += timeChange;
			if(scaleTimer >= SCALE_TIME){
				isDeformed = true;
				reform(1/scale);
				scaleTimer = 0;
			}
		}
		
		// deforms, only difference from reform is that reform does not care if it is deformed or not; skews one x vertex
		public function deform(scale:Number){
			this.scale = scale;
			
			graphics.clear();
			if(isDeformed){
				
				tempX = Math.random() * shape.vertices.length; //Pick a random x vertex							 
			
				oldX = shape.vertices[tempX].x;	//Store the old x
								
				for (var j:int=0; j < shape.vertices.length; j++) {
					shape.vertices[j].x *= scale;
					shape.vertices[j].y *= scale;					
				}
				
				shape.vertices[tempX].x = (shape.vertices[tempX].x + (skewX * shape.vertices[tempX].x)); //Skew the x value
								
				isDeformed = false;
			}
			shape.renderVertices();
		}
		
		public function reform(scl:Number){
			shape.graphics.clear();
			this.scale = 1;

			for (var j:int=0; j < shape.vertices.length; j++) {
				shape.vertices[j].x *= scl;
				shape.vertices[j].y *= scl;
			}
			
			shape.vertices[tempX].x = oldX; //Unskew the vertex
			
			shape.renderVertices();
		}
		
		public function updateQuadTree(oldLines:Array, newLines:Array, quadTree:QuadTree):QuadTree{
			for each(var l:Line in oldLines){
				if(l.a != null && l.b != null){
					var deleteQuad = quadTree.getContainingQuadLine(l);
					deleteQuad.deleteObject(l);  // finds the proper place in the quadtree for l and deletes it
				}
			}
			for each(var newL:Line in newLines){
				if(newL.a != null && newL.b != null)
					quadTree.addObject(newL);
			}
			return quadTree;
		}
	}
	
}
